//#pragma once

#ifndef __GRAPH__
#define __GRAPH__

#include <set>

using namespace std;

enum type {add = 1, multiplication = 2};
enum cptype {cpofsub = 1, cpofpred = 2, cpofpredresv = 3, cpofnodes = 4, cpofpred_ = 5, cpofsub_ = 6, cpofpredresv_ = 7};
enum search_strategy { onephase = 1, twophase = 2 };

class Graph;
class Dependency;
class Operation;

class Graph
{
public:
  Graph ( void );
  ~Graph ( void );

  set<Operation*> operations;
  set<Dependency*> dependencies;
  set<Operation*> sourceOps;
  set<Operation*>  sinkOp;
  void initGraph();
};

class Dependency
{
public:
  int id;
  Dependency ( void );
  ~Dependency ( void );

  Operation *source;
  Operation *sink;
  Dependency ( Operation * source, Operation * sink );
};

class Operation
{
public:
  Operation ( void );
  ~Operation ( void );
  // predefined id
  int id;
  // step in current schedule
  int step;
  // operation type
  type t;
  int level;
  int ASAP;
  int asapuc;
  int ALAP;
  int alapuc;
  int inD;
  int outD;
  int delay;
  Graph *g;
  set<Dependency*> adj;
  set<Dependency*> in;
  set<Operation*> precedent;
  set<Operation*> children;
  bool visited;
  Operation* base_addr;
  int CPSubGraph;
  int CPPredGraph;
  int CPofPreRevGraph;

  float sort_id;

  int level_l;
  int level_h;

  int graph;

  Operation * sortedOp;
};

#endif
